/**
 * @file hash_util.cpp
 * @brief 哈希工具类实现
 */

#include "hash_util.h"
#include "logger.hpp"
#include <openssl/sha.h>
#include <fstream>
#include <iomanip>
#include <sstream>

/**
 * @brief 计算文件的SHA-256哈希值
 */
std::string HashUtil::calculateFileSHA256(const std::string& file_path) 
{
    std::ifstream file(file_path, std::ios::binary);
    if (!file.is_open()) 
    {
        Log::GetLogger("asynclogger")->Info("无法打开文件: %s", file_path.c_str());
        return "";
    }
    
    SHA256Context ctx;
    char buffer[8192]{};  // 8KB缓冲区，优化IO性能
    
    while (file.read(buffer, sizeof(buffer)) || file.gcount() > 0) 
    {
        if (!ctx.update(buffer, file.gcount())) 
        {
            Log::GetLogger("asynclogger")->Info("哈希计算失败: %s", file_path.c_str());
            return "";
        }
    }
    
    return ctx.finalize();
}

/**
 * @brief 计算数据的SHA-256哈希值
 */
std::string HashUtil::calculateDataSHA256(const void* data, size_t size) 
{
    SHA256Context ctx;
    if (!ctx.update(data, size)) 
    {
        Log::GetLogger("asynclogger")->Warn("哈希计算失败");
        return "";
    }
    return ctx.finalize();
}

/**
 * @brief 计算字符串的SHA-256哈希值
 */
std::string HashUtil::calculateStringSHA256(const std::string& str) 
{
    return calculateDataSHA256(str.data(), str.size());
}

/**
 * @brief 将字节数组转换为十六进制字符串
 */
std::string HashUtil::bytesToHex(const unsigned char* bytes, size_t size) 
{
    std::ostringstream oss;
    for (size_t i = 0; i < size; ++i) 
    {
        oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(bytes[i]);
    }
    return oss.str();
}

/**
 * @brief SHA256Context构造函数
 */
HashUtil::SHA256Context::SHA256Context() : finalized_(false) 
{
    ctx_ = new SHA256_CTX;
    SHA256_Init(static_cast<SHA256_CTX*>(ctx_));
}

/**
 * @brief SHA256Context析构函数
 */
HashUtil::SHA256Context::~SHA256Context() 
{
    delete static_cast<SHA256_CTX*>(ctx_);
    ctx_ = nullptr;
}

/**
 * @brief 更新哈希计算
 */
bool HashUtil::SHA256Context::update(const void* data, size_t size) 
{
    if (finalized_) 
    {
        Log::GetLogger("asynclogger")->Info("尝试在已完成的哈希上下文上更新数据");
        return false;
    }
    
    return SHA256_Update(static_cast<SHA256_CTX*>(ctx_), data, size) == 1;
}

/**
 * @brief 完成哈希计算并获取结果
 */
std::string HashUtil::SHA256Context::finalize() 
{
    if (finalized_) 
    {
        Log::GetLogger("asynclogger")->Info("哈希上下文已经完成计算");
        return "";
    }
    
    unsigned char hash[SHA256_DIGEST_LENGTH];
    if (SHA256_Final(hash, static_cast<SHA256_CTX*>(ctx_)) != 1) 
    {
        Log::GetLogger("asynclogger")->Info("SHA256计算失败");
        return "";
    }
    
    finalized_ = true;
    return bytesToHex(hash, SHA256_DIGEST_LENGTH);
}

/**
 * @brief 重置哈希上下文
 */
void HashUtil::SHA256Context::reset() 
{
    SHA256_Init(static_cast<SHA256_CTX*>(ctx_));
    finalized_ = false;
} 